package com.gxa.learning.pc.service.impl;

import com.gxa.learning.core.common.ExceptionCode;
import com.gxa.learning.core.exception.BusinessException;
import com.gxa.learning.core.pojo.*;
import com.gxa.learning.core.service.impl.BaseServiceImpl;
import com.gxa.learning.pc.mapper.*;
import com.gxa.learning.pc.service.ProjectApplyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.sql.Timestamp;
import java.util.List;
import java.util.Map;

@Service
@Transactional(rollbackFor = Throwable.class)
public class ProjectApplyServiceImpl extends BaseServiceImpl<ProjectApply> implements ProjectApplyService {
    @Autowired
    private ProjectApplyMapper projectApplyMapper = null;

    @Autowired
    private UserMapper userMapper = null;

    @Autowired
    private ProjectMapper projectMapper = null;

    @Autowired
    private ProjectDetailsMapper projectDetailsMapper = null;

    @Autowired
    private FeedbackMapper feedbackMapper;

    @Override
    public void projectApply(Long pid, Long uid) throws Exception {
        if (pid == null || uid == null) {
            throw new BusinessException(ExceptionCode.ARGUMENTS_ERROR);
        }
        Project project = projectMapper.selectByPrimaryKey(pid);
        //判断加入的用户和项目是否存在
        if (project == null) {
            throw new BusinessException(ExceptionCode.NO_SUCH_OBJ);
        }
        //不知道为啥用byPrimaryKey不行
        Example userExample = new Example(User.class);
        Example.Criteria userCriteria = userExample.createCriteria();
        userCriteria.andEqualTo("id", uid);
        User user = userMapper.selectOneByExample(userExample);

        if (user == null) {
            throw new BusinessException(ExceptionCode.NO_SUCH_OBJ);
        }
        Example example = new Example(ProjectApply.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("userId", uid);
        criteria.andEqualTo("projectId", pid);
        ProjectApply projectApply = projectApplyMapper.selectOneByExample(example);
        //判断是否已将申请了同样的培训项目
        if (projectApply != null) {
            throw new BusinessException(ExceptionCode.HAS_SUCH_PROJECT);
        }
        Example detailsExaple = new Example(ProjectDetails.class);
        Example.Criteria detailsCriteria = detailsExaple.createCriteria();
        detailsCriteria.andEqualTo("projectId", pid);
        ProjectDetails projectDetails = projectDetailsMapper.selectOneByExample(detailsExaple);
        if (projectDetails == null) {
            throw new BusinessException(ExceptionCode.WRONG_PROJECT);
        }
        ProjectApply thisApply = new ProjectApply();
        //判断添加的项目是否是需要审核的,不需要就直接同过
        if (projectDetails.getApplyRequired()) {
            thisApply.setApplyStatus(1);
        } else {
            thisApply.setApplyStatus(0);
        }
        thisApply.setProjectId(pid);
        thisApply.setUserId(uid);
        //是否支付状态，没有做就默认全部都支付了
        thisApply.setPay(true);
        int insert = projectApplyMapper.insert(thisApply);
        insetFeed(uid, pid);
        if (insert < 1) {
            throw new BusinessException(ExceptionCode.FAILED_OPTION);
        }
    }

    @Override
    public List<Map<String, Object>> getStudents(Long pid, String name, String company, String position, Integer page, Integer size) throws BusinessException {
        if (pid == null || pid < 1) {
            throw new BusinessException(ExceptionCode.ARGUMENTS_ERROR);
        }
        if (page == null || page <= 0) {
            page = 1;
        }
        if (size == null || size <= 0) {
            size = 5;
        }
        Integer start = (page - 1) * size;
        List<Map<String, Object>> students = projectApplyMapper.getStudents(pid, name, company, position, start, size);
        if (students == null || students.size() == 0) {
            throw new BusinessException(ExceptionCode.WRONG_DATA);
        }
        return students;
    }

    @Override
    public Integer getStudentsCount(Long pid, String name, String company, String position) throws BusinessException {
        if (pid == null || pid < 1) {
            throw new BusinessException(ExceptionCode.ARGUMENTS_ERROR);
        }
        List<Map<String, Object>> students = projectApplyMapper.getStudents(pid, name, company, position, null, null);
        if (students == null || students.size() <= 0) {
            throw new BusinessException(ExceptionCode.WRONG_DATA);
        }
        return students.size();
    }

    @Override
    public List<Map<String, Object>> getAllStudents(Long pid, String name, String company, String position) throws BusinessException {
        if (pid == null || pid < 1) {
            throw new BusinessException(ExceptionCode.ARGUMENTS_ERROR);
        }
        List<Map<String, Object>> students = projectApplyMapper.getStudents(pid, name, company, position, null, null);
        if (students == null || students.size() == 0) {
            throw new BusinessException(ExceptionCode.WRONG_DATA);
        }
        return students;
    }

    @Override
    public Integer setApplyStatus(List<Long> applyIds, Integer status) throws Exception {
        Integer count = 0;
        //修改申请的状态信息，若申请成功了则会成为本项目的学员
        if (applyIds == null || applyIds.size() == 0 || status == null) {
            throw new BusinessException(ExceptionCode.ARGUMENTS_ERROR);
        }
        Example example = new Example(ProjectApply.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andIn("applyId", applyIds);
        List<ProjectApply> projectApplies = projectApplyMapper.selectByExample(example);
        if (projectApplies == null) {
            throw new BusinessException(ExceptionCode.NO_SUCH_OBJ);
        }
        if (status > 2 || status < 0) {
            throw new BusinessException(ExceptionCode.WRONG_OPTION);
        }

        for (ProjectApply projectApply : projectApplies) {
            projectApplyMapper.setApplyStatus(projectApply.getApplyId(), status);
            if (status == 1) {
                insetFeed(projectApply.getUserId(), projectApply.getProjectId());
            }
            count++;
        }
        if (count < 1) {
            throw new BusinessException(ExceptionCode.INVALID_OPERATION);
        }
        return count;
    }

    @Override
    public List<Map<String, Object>> getAllApply(Long pid, Integer page, Integer size) throws BusinessException {
        if (pid == null) {
            throw new BusinessException(ExceptionCode.ARGUMENTS_ERROR);
        }
        if (page == null || page < 1) {
            page = 1;
        }
        if (size == null || size < 1) {
            size = 5;
        }
        Integer offset = (page - 1) * size;
        List<Map<String, Object>> allApply = projectApplyMapper.getAllApply(pid, offset, size);
        if (allApply == null || allApply.size() == 0) {
            throw new BusinessException(ExceptionCode.WRONG_DATA);
        }
        return allApply;
    }

    @Override
    public Integer getAllApplyCount(Long pid) throws BusinessException {
        if (pid == null) {
            throw new BusinessException(ExceptionCode.ARGUMENTS_ERROR);
        }
        List<Map<String, Object>> allApply = projectApplyMapper.getAllApply(pid, null, null);
        if (allApply == null || allApply.size() <= 0) throw new BusinessException(ExceptionCode.WRONG_DATA);
        return allApply.size();
    }

    @Override
    public void delStudent(Long id) throws BusinessException {
        if (id == null || id < 1) {
            throw new BusinessException(ExceptionCode.ARGUMENTS_ERROR);
        }
        projectApplyMapper.deleteApply(id);
    }

    /**
     * 用户报名成功 审核通过之后同时在反馈表添加一条数据
     *
     * @param userId    用户编号
     * @param projectId 项目编号
     */
    @Override
    public void insetFeed(Long userId, Long projectId) throws Exception {
        Map<String, Object> userState = feedbackMapper.getUserState(userId, projectId);
        Feedback feedback = new Feedback();
        feedback.setUserId(userId);
        feedback.setProjectId(projectId);
        Object applyStatus = userState.get("apply_status");
        Timestamp projectStartTime = (Timestamp) userState.get("project_startTime");
        if (applyStatus == null || projectId == null) {
            throw new BusinessException(ExceptionCode.INVALID_OPERATION);
        }
        if ((int) applyStatus == 1) {
//         当前时间小于项目开始时间
            if (new Timestamp(System.currentTimeMillis()).before(projectStartTime)) {
//                则表示未开始
                feedback.setState(-1);
            } else {
//                当前时间大于项目开始时间 则表示已开始
                feedback.setState(0);
            }
        }
        int i = feedbackMapper.insertSelective(feedback);
        if (i < 1) {
            throw new BusinessException(ExceptionCode.INVALID_OPERATION);
        }
    }
}
